<template>
    <div class="customBox modelBox">
        <h3 class="title">
            数据模型
            <el-button style="float: right;" type="success" size="mini" round @click="newModel" circle>
                <i class="el-icon-plus"></i>
            </el-button>
        </h3>

        <el-input class="modelSeatchInput" v-model="keyStr" clearable placeholder="key值筛选"></el-input>
        <el-row class="modalItem" v-for="(item, index) in models" :key="index">
            <el-col :span="24" class="modelName">{{item.key}} <span style="color: #999;">{{item.modelName}}</span>
            </el-col>
            <el-col :span="24">
                <el-button class="miniButton" size="mini" type="danger" icon="el-icon-delete" round
                    @click="deleteModel(index)">删除
                </el-button>
                <el-button class="miniButton" size="mini" type="warning" icon="el-icon-edit-outline"
                    @click="editModel(item)" round>编辑
                </el-button>
                <el-button class="miniButton" size="mini" type="primary" icon="el-icon-check" round
                    @click="useString(item)">载入
                </el-button>
                <el-button class="miniButton" size="mini" type="success" icon="el-icon-view" round
                    @click="viewModel(item)">预览
                </el-button>
            </el-col>
        </el-row>

        <el-dialog title="模型编辑" append-to-body :class="theme" :visible.sync="showEditor" width="800px">
            <el-row :gutter="5" style="padding: 0 0 5px 0;">
                <el-col :span="3" style="line-height: 40px;">类名:</el-col>
                <el-col :span="12">
                    <el-input v-model="activeObject.key" placeholder="类名不能为空"></el-input>
                </el-col>
                <el-col :span="9">
                    <el-button style="float: right;" icon="el-icon-edit-outline" @click="showJsonEditorEvent" round>
                        用Java代码中导入模型
                    </el-button>
                </el-col>
            </el-row>
            <el-row :gutter="5" style="padding: 0 0 5px 0;">
                <el-col :span="3" style="line-height: 40px;">备注名 :</el-col>
                <el-col :span="12">
                    <el-input v-model="activeObject.modelName" placeholder="备注名"></el-input>
                </el-col>
            </el-row>
            <br>
            <el-row :gutter="5" style="padding: 0 0 5px 0;" v-for="(formitem, index) in activeObject.itemArray"
                :key="index">
                <el-col :span="6">
                    <el-input v-model="formitem.key" @input="change('key', index)" placeholder="Key值"></el-input>
                </el-col>
                <el-col :span="4">
                    <el-select style="width: 100%;" :popper-class="theme" filterable default-first-option allow-create
                        :class="theme" @change="change('type', index)" placeholder="请选择" v-model="formitem.type">
                        <el-option v-for="item in typeArray" :class="theme" :key="item.value" :label="item.label"
                            :value="item.value">
                        </el-option>
                    </el-select>
                </el-col>
                <el-col :span="12">
                    <div>
                        <el-input placeholder="备注" @input="change('annotate', index)" v-model="formitem.annotate">
                        </el-input>
                    </div>
                </el-col>
                <el-col :span="2" class="deleteItem">
                    <el-button type="danger" size="mini" @click="deleteItem(index)" circle icon="el-icon-delete">
                    </el-button>
                </el-col>
            </el-row>
            <span slot="footer" class="dialog-footer">
                <el-button type="primary" size="samll">保存</el-button>
            </span>
        </el-dialog>

        <el-dialog title="从代码中导入" append-to-body :class="theme" :visible.sync="showJavaEditor" width="600px">
            <el-input class="CodeMirror-custom" type="textarea" :rows="10" resize="none" v-model="javaCode"></el-input>
            <span slot="footer" class="dialog-footer">
                <el-button type="primary" size="samll" @click="formatJavaCode">提交</el-button>
            </span>
        </el-dialog>

        <el-dialog title="预览" append-to-body :class="theme" :visible.sync="showJsonEditor" width="600px">
            <el-input class="CodeMirror-custom" type="textarea" :rows="10" resize="none" v-model="jsonCode"></el-input>
            <span slot="footer" class="dialog-footer">
                <el-button type="primary" size="samll" @click="useView">载入</el-button>
            </span>
        </el-dialog>

    </div>
</template>
<script>
    import { mapState } from 'vuex';

    export default {
        data() {
            return {
                jsonCode: '',
                showJavaEditor: false,
                showJsonEditor: false,
                keyStr: '',
                showEditor: false,
                activeObject: {},
                javaCode: '',
            }
        },
        computed: {
            ...mapState("theme", {
                theme: state => state.theme,
            }),
            ...mapState("customKey", {
                editObj: state => state.activeObj,
            }),
            ...mapState("model", {
                models: state => state.models,
                typeArray: state => state.typeArray,
            }),
        },
        methods: {
            useView() {
                this.showJsonEditor = false;
                this.editObj.setValue(this.jsonCode);
                this.$store.dispatch('customKey/colseCustomDrawer');
            },
            useString(item) {
                var str = this.renderData(item);
                str = (str.substring(str.length - 1) == ',') ? str.substring(0, str.length - 1) : str;
                this.editObj.setValue(str);
                this.$store.dispatch('customKey/colseCustomDrawer');
            },
            change(type, index) {
                if (this.activeObject.itemArray.length - 1 == index) {
                    this.activeObject.itemArray.push({
                        key: '',
                        type: '',
                        annotate: '',
                    });
                };
            },
            newModel() {
                this.showEditor = true;
                this.activeObject = {
                    key: '',
                    modelName: '',
                    itemArray: [{
                        key: '',
                        type: '',
                        annotate: '',
                    }]
                };
            },
            viewModel(item) {
                var str = this.renderData(item);
                str = (str.substring(str.length - 1) == ',') ? str.substring(0, str.length - 1) : str;
                this.jsonCode = str;
                this.showJsonEditor = true;
            },
            inArray(string, _array) {
                var index = -1;
                for (let i = 0; i < _array.length; i++) {
                    const element = _array[i];
                    if (element == string) {
                        index = i;
                        break;
                    };
                };
                return index;
            },
            beautify(source) {
                function looks_like_html(source) {
                    var trimmed = source.replace(/^[ \t\n\r]+/, '');
                    return trimmed && (trimmed.substring(0, 1) === '<');
                };
                var output,
                    opts = {
                        // brace_style : "expand"
                    };
                opts.indent_char = ' ';
                opts.preserve_newlines = "-1";
                if (looks_like_html(source)) {
                    output = html_beautify(source, opts);
                } else {
                    output = js_beautify(source, opts);
                };
                return output;
            },
            renderData(data, annotate) {
                let typeArray = ['Long', 'Integer', 'Short', 'Byte', 'Float', 'Double', 'Boolean', 'Char', 'String', 'Date'];
                let Items = {};
                for (let i = 0; i < this.models.length; i++) {
                    const element = this.models[i];
                    Items[element.key] = element;
                };
                var _String = '{'
                if (annotate) {
                    _String += annotate
                };
                for (let i = 0; i < data.itemArray.length; i++) {
                    var item = data.itemArray[i];
                    var __type = item.type.replace(/ /g, '');
                    if (this.inArray(__type, typeArray) >= 0) {
                        _String += (item.key + ':' + '\'\',' + ' // ' + item.annotate + ' (' + item.type + ')\n');
                    } else if (item.type.indexOf('List') >= 0) {
                        var _type = item.type.substring(item.type.indexOf('<') + 1, item.type.indexOf('>'));
                        if (this.inArray(_type, typeArray) >= 0) {
                            _String += (item.key + ': [],' + ' // ' + item.annotate + ' (' + item.type + ')\n');
                        } else {
                            _String += (item.key + ': [' + ' // ' + item.annotate + ' (' + item.type + ')\n');
                            if (Items.hasOwnProperty(_type)) {
                                _String += this.renderData(Items[_type]);
                            } else {
                                _String += ('{},\n');
                            };
                            _String += ('],\n');
                        };
                    } else {
                        if (Items.hasOwnProperty(__type)) {
                            _String += (item.key + ': ');
                            _String += this.renderData(Items[__type], ' // ' + item.annotate + ' (' + item.type + ')\n');
                            _String += ('\n');
                        } else {
                            _String += (item.key + ': {},' + ' // ' + item.annotate + ' (' + item.type + ')\n');
                        };
                    }
                };
                _String += '},'
                return this.beautify(_String)
            },
            editModel(item) {
                this.showEditor = true;
                this.activeObject = JSON.parse(JSON.stringify(item));
                this.activeObject.itemArray.push({
                    key: '',
                    type: '',
                    annotate: '',
                });
            },
            showJsonEditorEvent() {
                this.showJavaEditor = true;
                this.javaCode = '';
            },
            deleteModel(index) {
                this.$confirm('是否删除数据模型？', '警告', {
                    customClass: this.theme
                }).then(_ => {
                    this.$store.dispatch('model/deleteModel', index);
                    console.log('delete');
                }).catch(_ => { });
            },
            deleteItem(index) {
                this.activeObject.itemArray.splice(index, 1);
                if (this.activeObject.itemArray.length == 0) {
                    this.activeObject.itemArray.push({
                        key: '',
                        type: '',
                        annotate: '',
                    });
                };
            },
            formatJavaCode() {
                var classNameReg = new RegExp("(?<=public class ).+(?=\s\{\s)");
                var modelKey = this.javaCode.match(classNameReg);
                var _stringArray = this.javaCode.split('//');
                var itemArray = [];
                for (let index = 0; index < _stringArray.length; index++) {
                    let element = '//' + _stringArray[index];
                    if (index != 0) {
                        var typeReg = new RegExp("(?<=private ).+(?=;)");
                        var typeString = element.match(typeReg)[0];
                        var _typeStringArray = typeString.split(' ');
                        var key = _typeStringArray[1];
                        var type = _typeStringArray[0];

                        var annotateReg = new RegExp("(?<=\/\/ ).+(?=\n)");
                        var annotate = element.match(annotateReg)[0];
                        var _obj = {
                            key: key,
                            type: type,
                            annotate: annotate,
                        };
                        itemArray.push(_obj);
                    };
                };
                this.activeObject.key = modelKey[0];
                this.activeObject.itemArray = itemArray;
                this.activeObject.itemArray.push({
                    key: '',
                    type: '',
                    annotate: '',
                });
                this.showJavaEditor = false;
            },
        },
    }
</script>